#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <hcsr04.h>

#define beep        D0
#define TRIG_PIN    D1
#define ECHO_PIN_M1 D5
#define ECHO_PIN_M2 D6
#define ECHO_PIN_M3 D7
#define ECHO_PIN_M4 D4
#define ECHO_PIN_M5 D2

HCSR04 hcsr04(TRIG_PIN, ECHO_PIN_M1, 20, 500, 332);

WiFiClient client;
boolean is_connect       = false;

char    TYPE             = 'Z';
String  id               = String(ESP.getChipId()) + String(ESP.getFlashChipId());
String  replyString      = "LIFANKO-" + String(TYPE) + "-" + id;

//const char* ssid = "hangrui";
//const char* password = "a6745282";
const char* ssid = "AndroidAP";
const char* password = "47333000";

unsigned long lastTime = 0;

void setup() {
  // Initial Pins
  pinMode(beep, OUTPUT);
  digitalWrite(beep, LOW);
  pinMode(TRIG_PIN, OUTPUT);
  digitalWrite(TRIG_PIN, HIGH);

  Serial.begin(115200);
  delay(100);

  Serial.println("\nSystem Started!");
  Serial.println("Device: " + replyString);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.print("Connecting Router");
  for (byte j = 0; j < 20; j++) {
    if (WiFi.status() == WL_CONNECTED) {
      is_connect = true;
      break;
    } else {
      Serial.print(".");
      delay(450);
      bee(50, 0);
    }
  }

  if (is_connect) {
    Serial.println("Success!");

    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());

    for (byte j = 1; j <= 3; j++) {
      bee(90, j * j * 10);
    }
  } else {
    Serial.println("Fail!");

    reset();
  }
}

void reset() {
  for (byte j = 3; j > 0; j--) {
    bee(40, j * j * 20);
  }
  delay(60000);

  ESP.restart();
}

void loop(void) {
  // check status
  if ((millis() - lastTime) > 60000) {
    if (WiFi.status() != WL_CONNECTED) {
      reset();
    }
    lastTime = millis();
  }

  byte i = 0;
  char rec[30] = {0};
  while (i < 30 && Serial.available() > 0) {
    char buf = Serial.read();

    rec[i++] = buf;
    delay(2);
  }
  if (i > 0) {
    i = 0;

    if (rec[0] == 'I' && rec[1] == 'n' && rec[2] == 'n' && rec[3] == 'e' && rec[4] == 'r' && rec[5] == '-' && rec[6] == 'S' && rec[7] == 'c' && rec[8] == 'a' && rec[9] == 'n') {
      bee(100, 0);

      char buf[16] = {0};
      byte k = 0;
      while (k < 16) {
        if (rec[k + 11] == '\r' || rec[k + 11] == '\n') {
          break;
        }

        buf[k] = rec[k + 11];
        k++;
      }

      byte index = ECHO_PIN_M1;
      switch (buf[1]) {
        case '2':
          index = ECHO_PIN_M2;
          break;
        case '3':
          index = ECHO_PIN_M3;
          break;
        case '4':
          index = ECHO_PIN_M4;
          break;
        case '5':
          index = ECHO_PIN_M5;
          break;
      }

      upload(String(mesure(index)), String(buf));
    }
  }
}

void upload(String distance, String filename) {
  String serverPath = "http://www.lifanko.cn/idp/yjsc/ultrasonic.php?id=" + id + "&dis=" + distance + "&name=" + filename;
  Serial.println(serverPath);

  HTTPClient http;
  http.begin(serverPath.c_str());

  // Send HTTP GET request
  int httpResponseCode = http.GET();

  if (httpResponseCode == 200) {
    bee(50, 150);
  } else {
    bee(50, 50);
  }

  // Free resources
  http.end();
}

int mesure(byte index) {
  int distance = 0;
  byte cnt = 0;
  byte i = 0;

  delay(150);

  while (++i < 10) {
    int dis = hcsr04.distanceInMillimeters(index);
    if (dis > 0) {
      distance += dis;
      cnt++;
      bee(50, 100);
    } else {
      bee(50, 150);
    }
    delay(150);

    if (cnt == 5) {
      break;
    }
  }

  return distance / cnt;
}

void bee(unsigned int t, byte f) {
  for (unsigned int i = 0; i < (1000 / (1000 - 2 * f))*t; i++) {
    digitalWrite(beep, HIGH);
    delayMicroseconds(500 - f);
    digitalWrite(beep, LOW);
    delayMicroseconds(500 - f);
  }
}
